/***********************************
 *  string.c					   *
 ***********************************/

#include "../include/string.h"
#include "../include/math.h"
#include "../include/defs.h"


char * reverse(char *str) {
	int j, i;
	char aux;

	for (j = 0, i = strlen(str) - 1; j < i; j++, i--) {
		aux = str[j];
		str[j] = str[i];
		str[i] = aux;
	}
	str[strlen(str)] = 0;

	return str;
}


char *
strncpy(char * dest, const char * src, unsigned int n)
{
    unsigned int i;

    for (i = 0 ; i < n && src[i] != '\0' ; i++)
        dest[i] = src[i];
    for ( ; i < n ; i++)
        dest[i] = '\0';

    return dest;
}


char *
strcpy(char * dest, char * src)
{
    unsigned int i;

    for (i = 0 ; src[i] != '\0' ; i++)
        dest[i] = src[i];

    dest[i] = '\0';

    return dest;
}


int strcmp(char *str1, char *str2) {
	while (*str1 != 0 && *str2 != 0) {
		if (*str1 < *str2)
			return -1;
		if (*str1 > *str2)
			return 1;
		str1++;
		str2++;
	}
	if (*str1 != 0)
		return -1;
	if (*str2 != 0)
		return 1;

	return 0;
}


int
strncmp(const char * s1, const char * s2, unsigned int n)
{
    int i;

    if(s1 == NULL && s2 != NULL)
        return 1;
    else if (s1 != NULL && s2 == NULL)
        return -1;
    else if (s1 == NULL && s2 == NULL)
        return 0;
    else
    {
        for (i = 0 ; i < n ; i++ )
        {
            if (s1[i] < s2[i])
                return -1;
            if (s1[i] > s2[i])
                return 1;
        }
    }

    /* Si llega aca es porque son iguales.*/
	return 0;
}


int strlen(char *str) {
	int i = 0;

	while (*(str++) != 0)
		i++;

	return i;
}


char *
strchr(char * s, int c)
{
    int i = 0;
    char * aux;

    aux = s;

    /* Recorre el arreglo, incluido su '\0' final por si el usuario invoca esta funcion con c = 0.*/
    while (i < strlen(aux) + 1)
    {
        if (*s++ == c)
            return (s - 1);
        i++;
    }

    return NULL;
}


void *
memcpy(void * dest, const void * src, unsigned int n)
{
    int i;
    unsigned char * current;

    if (dest == NULL || src == NULL || n <= 0)
        return NULL;

    for (i = 0 ; i < n ; i++)
    {
        /* Si hay memory overlap (dest interseccion src != vacio, falla la copia.*/
        if ( (unsigned char *)dest + i * sizeof(char) == ( (unsigned char *)src ) + i * sizeof(char) )
            return NULL;

        /* Obtiene la direccion del byte a donde tiene que escribir.*/
        current = (unsigned char *)dest + i * sizeof(char);

        /* Escribe sobre esa posición de memoria.*/
        *current = *((unsigned char *)src + i * sizeof(char));
    }

    return dest;
}


void *
memsetw(void * s, int c, unsigned int n)
{
    int i;
    unsigned short * current;

    if (s == NULL || n <= 0)
        return NULL;

    for (i = 0 ; i < n ; i++)
    {
        current = (unsigned short *)((unsigned char *)s + i * sizeof(unsigned short));
        *current = (unsigned short)c;
    }

    return s;
}


void *
memset(void * s, int c, unsigned int n)
{
    int i;
    unsigned char * current;

    if (s == NULL || n <= 0)
        return NULL;

    for (i = 0 ; i < n ; i++)
    {
        current = (unsigned char *)s + i * sizeof(unsigned char);
        *current = (unsigned char)c;
    }

    return s;
}

/*Fuente: http://en.wikibooks.org/wiki/Programming:C_strings#The_memcmp_function*/
int memcmp(const void *s1, const void *s2, int n)
{
    unsigned char *us1 = (unsigned char *) s1;
    unsigned char *us2 = (unsigned char *) s2;
    while (n-- != 0)
    {
        if (*us1 != *us2)
            return (*us1 < *us2) ? -1 : +1;
        us1++;
        us2++;
    }
    return 0;
}


void intToString(char *buf, int num) {
	int i = 0, flag = 0;
	if (num == 0)
		buf[i++] = '0';

	if (num < 0) {
		flag = 1;
		num = num * -1;
	}

	while (num > 0) {
		buf[i++] = (num % 10) + '0';
		num = num / 10;
	}
	if (flag == 1) {
		buf[i++] = '-';
	}
	buf[i] = 0;
	reverse(buf);
}


